package com.wontube.smr.bo.sites;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;

import com.wontube.client.extension.utils.net.URLUtils;
import com.wontube.core.dao.mybatis.QueryExample;

import com.wontube.smr.client.model.po.Movie;
import com.wontube.smr.client.model.po.TVEpisode;
import com.wontube.smr.client.model.po.TVShow;
import com.wontube.smr.dao.mapper.MovieGenreMapper;
import com.wontube.smr.dao.mapper.MovieMapper;
import com.wontube.smr.dao.mapper.MovieTodayMapper;
import com.wontube.smr.dao.mapper.MovieWeekMapper;
import com.wontube.smr.dao.mapper.PopularEpisodeMapper;
import com.wontube.smr.dao.mapper.RecentEpisodeMapper;
import com.wontube.smr.dao.mapper.RecentMovieMapper;
import com.wontube.smr.dao.mapper.RecentShowMapper;
import com.wontube.smr.dao.mapper.TVEpisodeMapper;
import com.wontube.smr.dao.mapper.TVSeasonMapper;
import com.wontube.smr.dao.mapper.TVShowGenreMapper;
import com.wontube.smr.dao.mapper.TVShowMapper;
import com.wontube.smr.pub.DefaultDBHelper;

/**
 * @author yuechao
 * 
 */
public final class VerifyUrlBO {
	private VerifyUrlBO() {
	}

	public static int cleanupTV(int dateDiff) {
		// 先检测网络是否是通的
		final String huluUrl = "http://www.hulu.com";
		if (!URLUtils.checkUrl(huluUrl)) {
			return 0;
		}
		
		int count = 0;
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DATE, dateDiff);

		QueryExample ex = new QueryExample();
		ex.or().addCriterion("tv_show.version < ", calendar.getTime());
		ex.setOrderByClause("tv_show.sort_index asc");
		int offset = 0;
		RowBounds rowBounds = new RowBounds(offset, 10);
		while (true) {
			List<TVShowTree> list = selectTVShow(ex, rowBounds);
			if (list.size() < 1) {
				break;
			}

			ArrayList<String> deleteShows = new ArrayList<String>();
			ArrayList<String> deleteEpisodes = new ArrayList<String>();
			for (TVShowTree tree : list) {
				if (!URLUtils.checkUrl(tree.tvShow.getItemUrl())) {
					deleteShows.add(tree.tvShow.getId());
					for (TVEpisode episode : tree.episodes) {
						deleteEpisodes.add(episode.getId());
					}
				} else {
					for (TVEpisode episode : tree.episodes) {
						if (!URLUtils.checkUrl(episode.getUrl())) {
							deleteEpisodes.add(episode.getId());
						}
					}
				}
			}

			count += deleteEpisodes.size() + deleteShows.size();
			if (deleteEpisodes.size() < 1 && deleteShows.size() < 1) {
				offset += rowBounds.getLimit();
				rowBounds = new RowBounds(offset, 10);
				continue;
			}
			
			SqlSession session = DefaultDBHelper.getBatchSqlSession();
			try {
				TVEpisodeMapper episodeMapper = session.getMapper(TVEpisodeMapper.class);
				PopularEpisodeMapper popularEpisodeMapper = session.getMapper(PopularEpisodeMapper.class);
				RecentEpisodeMapper recentEpisodeMapper = session.getMapper(RecentEpisodeMapper.class);

				QueryExample deleteEx = new QueryExample();
				for (String episodeId : deleteEpisodes) {
					deleteEx.clear();
					deleteEx.or().addCriterion("popular_episode.episode_id = ", episodeId);
					popularEpisodeMapper.deleteByExample(deleteEx);

					deleteEx.clear();
					deleteEx.or().addCriterion("recent_episode.episode_id = ", episodeId);
					recentEpisodeMapper.deleteByExample(deleteEx);

					episodeMapper.deleteByPrimaryKey(episodeId);
				}

				RecentShowMapper recentShowMapper = session.getMapper(RecentShowMapper.class);
				for (String showId : deleteShows) {
					deleteEx.clear();
					deleteEx.or().addCriterion("recent_show.show_id =", showId);
					recentShowMapper.deleteByExample(deleteEx);
				}
				
				if (deleteShows.size() > 0) {
					deleteEx.clear();
					deleteEx.or().addCriterion("tvshow_genre.show_id in", deleteShows);
					TVShowGenreMapper genreMapper = session.getMapper(TVShowGenreMapper.class);
					genreMapper.deleteByExample(deleteEx);
		
					deleteEx.clear();
					deleteEx.or().addCriterion("tv_season.show_id in", deleteShows);
					TVSeasonMapper seasonMapper = session.getMapper(TVSeasonMapper.class);
					seasonMapper.deleteByExample(deleteEx);
					
					deleteEx.clear();
					deleteEx.or().addCriterion("tv_show.id in", deleteShows);
					TVShowMapper tvShowMapper = session.getMapper(TVShowMapper.class);
					tvShowMapper.deleteByExample(deleteEx);
				}
				session.commit();
			} finally {
				session.close();
			}
			
			offset += (rowBounds.getLimit() - deleteShows.size());
			rowBounds = new RowBounds(offset, 10);
		}
		
		return count;
	}

	public static int cleanupMovie(int dateDiff) {
		// 先检测网络是否是通的
		if (!URLUtils.checkUrl("http://www.hulu.com") || !URLUtils.checkUrl("http://www.vevo.com")) {
			return 0;
		}
		
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DATE, dateDiff);

		QueryExample ex = new QueryExample();
		ex.or().addCriterion("movie.version < ", calendar.getTime());
		ex.setOrderByClause("movie.sort_index asc");
		int count = 0;
		int offset = 0;
		RowBounds rowBounds = new RowBounds(offset, 10);
		while (true) {
			List<Movie> list = selectMovie(ex, rowBounds);
			if (list.size() < 1) {
				break;
			}

			ArrayList<String> deleteMovies = new ArrayList<String>();
			for (Movie movie : list) {
				if (!URLUtils.checkUrl(movie.getItemUrl())) {
					deleteMovies.add(movie.getId());
				}
			}

			count += deleteMovies.size();
			if (deleteMovies.size() < 1) {
				offset += rowBounds.getLimit();
				rowBounds = new RowBounds(offset, 10);
				continue;
			}
			
			SqlSession session = DefaultDBHelper.getBatchSqlSession();
			try {
				MovieWeekMapper movieWeekMapper = session.getMapper(MovieWeekMapper.class);
				MovieTodayMapper movieTodayMapper = session.getMapper(MovieTodayMapper.class);
				RecentMovieMapper recentMovieMapper = session.getMapper(RecentMovieMapper.class);
				MovieGenreMapper movieGenreMapper = session.getMapper(MovieGenreMapper.class);
				MovieMapper movieMapper = session.getMapper(MovieMapper.class);

				QueryExample deleteEx = new QueryExample();
				for (String movieId : deleteMovies) {
					deleteEx.clear();
					deleteEx.or().addCriterion("movie_week.movie_id = ", movieId);
					movieWeekMapper.deleteByExample(deleteEx);

					deleteEx.clear();
					deleteEx.or().addCriterion("movie_today.movie_id = ", movieId);
					movieTodayMapper.deleteByExample(deleteEx);

					deleteEx.clear();
					deleteEx.or().addCriterion("recent_movie.movie_id = ", movieId);
					recentMovieMapper.deleteByExample(deleteEx);
					
					deleteEx.clear();
					deleteEx.or().addCriterion("movie_genre.movie_id = ", movieId);
					movieGenreMapper.deleteByExample(deleteEx);
					
					movieMapper.deleteByPrimaryKey(movieId);
				}
				
				session.commit();
			} finally {
				session.close();
			}
			
			offset += (rowBounds.getLimit() - deleteMovies.size());
			rowBounds = new RowBounds(offset, 10);
		}
		
		return count;
	}

	private static List<Movie> selectMovie(QueryExample ex, RowBounds rowBounds) {
		ArrayList<Movie> listResult = new ArrayList<Movie>();
		SqlSession session = DefaultDBHelper.getBatchSqlSession();
		try {
			MovieMapper movieMapper = session.getMapper(MovieMapper.class);
			List<Movie> listMovie = movieMapper.selectByExample(ex, rowBounds);
			if (listMovie.size() < 1) {
				return listResult;
			}
		} finally {
			session.close();
		}

		return listResult;
	}
	
	private static List<TVShowTree> selectTVShow(QueryExample ex, RowBounds rowBounds) {
		ArrayList<TVShowTree> listResult = new ArrayList<TVShowTree>();
		SqlSession session = DefaultDBHelper.getBatchSqlSession();
		try {
			TVShowMapper tvShowMapper = session.getMapper(TVShowMapper.class);
			List<TVShow> listShow = tvShowMapper.selectByExample(ex, rowBounds);
			if (listShow.size() < 1) {
				return listResult;
			}

			TVEpisodeMapper episodeMapper = session.getMapper(TVEpisodeMapper.class);
			QueryExample episodeEx = new QueryExample();
			for (TVShow tvShow : listShow) {
				episodeEx.clear();
				episodeEx.or().addCriterion("tv_episode.show_id = ", tvShow.getId());
				List<TVEpisode> episodes = episodeMapper.selectWith(episodeEx);
				TVShowTree tree = new TVShowTree();
				tree.tvShow = tvShow;
				tree.episodes = episodes;

				listResult.add(tree);
			}
		} finally {
			session.close();
		}

		return listResult;
	}
}

final class TVShowTree {
	public TVShow tvShow;
	public List<TVEpisode> episodes;
}
